package com.billow.net
{
	import com.billow.events.ClientEvent;
	import com.billow.events.ServerEvent;
	
	import flash.events.EventDispatcher;
	import flash.events.ServerSocketConnectEvent;
	import flash.net.ServerSocket;
	import flash.utils.ByteArray;
	
	[Event(name="login", type="com.billow.events.ServerEvent")]
	[Event(name="close", type="com.billow.events.ServerEvent")]
	[Event(name="receive", type="com.billow.events.ServerEvent")]
	[Event(name="succeed", type="com.billow.events.ServerEvent")]
	[Event(name="failed", type="com.billow.events.ServerEvent")]
	
	public class Server extends EventDispatcher
	{
		private const _onlineItems:Array = [];
		private var _key:String;
		private var _serverSocket:ServerSocket;
		
		public function Server(key:String)
		{
			super();
			_key = key;
		}
		
		
		////////////////////////////////////////////////////////////////////
		//
		//  get
		//
		///////////////////////////////////////////////////////////////////
		
		/**
		 * 在线用户列表 
		 * @return 
		 * 
		 */		
		public function get onlineItems():Array {return _onlineItems;}
		
		
		
		////////////////////////////////////////////////////////////////////
		//
		//  public
		//
		///////////////////////////////////////////////////////////////////
		
		
		/**
		 *  开启服务
		 * @param localPort
		 * @param localAddress
		 * 
		 */		
		public function bind(localPort:int, localAddress:String):void
		{
			try{
				_serverSocket = new ServerSocket();
				if(_serverSocket.bound)
				{
					_serverSocket.close();
					_serverSocket = new ServerSocket();
				}
				_serverSocket.bind(localPort, localAddress);
				_serverSocket.addEventListener(ServerSocketConnectEvent.CONNECT, onConnect);
				_serverSocket.listen();
				dispatchEvent(new ServerEvent(ServerEvent.SUCCEED));
			}catch(e:Error){
				dispatchEvent(new ServerEvent(ServerEvent.FAILED));
			}
		}
		
		
		/**
		 *  关闭服务
		 * 
		 */		
		public function close():void
		{
			if(_serverSocket!=null)
			{
				if(_serverSocket.bound)_serverSocket.close();
				_serverSocket.removeEventListener(ServerSocketConnectEvent.CONNECT, onConnect);
				_serverSocket = null;
			}
		}
		
		
		
		
		
		////////////////////////////////////////////////////////////////////
		//
		//  Event
		//
		///////////////////////////////////////////////////////////////////
		
		/**
		 * 用户连接 
		 * @param event
		 * 
		 */		
		private function onConnect(event:ServerSocketConnectEvent):void
		{
			var client:Client = new Client(_key ,0 ,event.socket);
			_onlineItems.push(client);
			client.addEventListener(ClientEvent.CONNECT_FAILED ,clientEventHandler);
			client.addEventListener(ClientEvent.RECEIVE ,clientEventHandler);
			dispatchEvent(new ServerEvent(ServerEvent.LOGIN ,client));
		}
		
		
		/**
		 * ClientEvent 客户端事件处理
		 * @param event
		 * 
		 */		
		private function clientEventHandler(event:ClientEvent):void
		{
			switch(event.type)
			{
				case ClientEvent.CONNECT_FAILED:
					/** 用户离开 */
					var client:Client = event.target as Client;
					var index:int = search(client.remoteAddress);
					if(index>-1)_onlineItems.splice(index ,1)[0];
					dispatchEvent(new ServerEvent(ServerEvent.CLOSE ,client));
					return;
					
				case ClientEvent.RECEIVE:
					/** 用户数据 */
					dispatchEvent(new ServerEvent(ServerEvent.RECEIVE ,event.target as Client));
					return;
			}
		}
		
		
		
		
		////////////////////////////////////////////////////////////////////
		//
		//  Function
		//
		///////////////////////////////////////////////////////////////////
		
		/**
		 * 搜索用户 
		 * @param remoteAddress
		 * @return 
		 * 
		 */		
		private function search(remoteAddress:String):int
		{
			for (var i:int=0;i<_onlineItems.length;i++)
			{
				if(_onlineItems[i].remoteAddress == remoteAddress)
					return i;
			}
			return -1;
		}
	}
}